home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacHack 1997
/
MacHack 1997.toast
/
Hacks
/
Hacks ’93
/
OK, What was that again?
/
Extension
/
OK.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-06-17
|
13KB
|
504 lines
#include <Dialogs.h>
#include <GestaltEqu.h>
#ifndef __TYPES__
#include <Types.h>
#endif
#ifndef __MEMORY__
#include <Memory.h>
#endif
#ifndef __ERRORS__
#include <Errors.h>
#endif
#ifndef __TRAPS__
#include <Traps.h>
#endif
#ifndef __OSUTILS__
#include <OSUtils.h>
#endif
#ifndef __TOOLUTILS__
#include <ToolUtils.h>
#endif
#ifndef __NOTIFICATION_
#include <Notification.h>
#endif
#include <Resources.h>
#include <StdDef.h>
#include <SysEqu.h>
#include "OSUtilsSup.h"
#include "Icons.h"
pascal void ShowINIT(short iconID, short moveX);
pascal void MessageModalDialog(ModalFilterProcPtr filterProc,short *itemHit);
pascal OSErr MessageGestalt(OSType selector, long *response);
pascal Boolean MessageFilterProc(DialogPtr theDialog, EventRecord* theEvent, short* itemHit);
void foo(void);
void Globals(void);
void PostNotification(void);
pascal OSErr DetachIcon(ResType, Handle* theIcon, void*);
typedef pascal void (*TModalDialog)(ModalFilterProcPtr, short*);
typedef struct SLocals {
struct SLocals* oldLocals;
long ticks;
ModalFilterProcPtr filterProc;
short stage;
Boolean timedOut;
Rect mouseSlop;
// GrafPort bwPort;
// GrafPort colorPort;
WindowPtr window;
Boolean isBWPort;
};
typedef struct SLocals SLocals;
struct SGlobals {
TModalDialog modalDialogProc;
SLocals* locals;
Handle iconSuites[6];
NMRec notifyRec;
};
typedef struct SGlobals SGlobals;
struct SMessage {
QHdr header;
NMRecPtr notify;
};
typedef struct SMessage SMessage;
void main(void)
{
SGlobals* globals = (SGlobals*)Globals;
Handle* iconSuite = &globals->iconSuites;
short i;
OSErr error;
THz zone;
Handle iconHandle;
SMessage* q = (SMessage*)foo;
q->header.qFlags = 0;
q->header.qHead = nil;
q->header.qTail = nil;
q->notify = nil;
NewGestalt('Msg!',(ProcPtr)MessageGestalt);
(void)PatchTrap((ProcPtr*)&globals->modalDialogProc, _ModalDialog, (ProcPtr)MessageModalDialog, 0);
DetachResource(RecoverHandle((Ptr)main));
zone = GetZone();
SetZone(SystemZone());
for (i = 512; i <= 517; ++i) {
error = GetIconSuite(iconSuite, i, svAllLargeData);
error = ForEachIconDo(*iconSuite, svAllLargeData, (ProcPtr)DetachIcon, nil);
++iconSuite;
}
iconHandle = GetResource('SICN', 128);
DetachResource(iconHandle);
HNoPurge(iconHandle);
globals->notifyRec.qType = nmType;
globals->notifyRec.nmMark = 0; // item to mark in Apple menu
globals->notifyRec.nmIcon = iconHandle; // handle to small icon
globals->notifyRec.nmSound = nil; // no sound
globals->notifyRec.nmStr = nil; // no alert
globals->notifyRec.nmResp = nil; // no response routine
SetZone(zone);
ShowINIT(128,-1);
}
pascal OSErr DetachIcon(ResType, Handle* theIcon, void*)
{
if (*theIcon) DetachResource(*theIcon);
return noErr;
}
void PostNotification(void)
{
SGlobals* globals = (SGlobals*)Globals;
SMessage* q = (SMessage*)foo;
// only post a notification if this is the first dialog dismissed since last viewed
if (q->header.qHead == nil) {
q->notify = &globals->notifyRec;
NMInstall(&globals->notifyRec);
}
}
void Globals(void)
{
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
}
void foo(void)
{
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
Debugger();
}
pascal OSErr MessageGestalt(OSType, long *response)
{
*response = (long)foo;
return noErr;
}
typedef struct {
struct QElem *qLink; /* QElement header */
short qType;
PicHandle picture;
unsigned long dateTime;
Rect windowRect;
Str31 appName;
} Q;
enum {
fingerFromLeft = 7,
fingerFromTop = 10,
fingerSize = 32,
lastStage = 5, /* Dismiss Dialog when this stage is met */
secondsPerStage = 1, /* Time for each stage */
startTime = 60 * 5, /* Start to fade after n seconds */
delayTime = 60 * secondsPerStage, /* Delta between stages in n seconds */
slopAmount = 4 /* Reset when mouse moves by this */
};
pascal void MessageModalDialog(ModalFilterProcPtr filterProc,short *itemHit)
{
SGlobals* globals = (SGlobals*)Globals;
PicHandle picture;
GrafPtr theDialog;
THz zone;
Q* q;
GrafPtr oldPort;
SMessage* message;
short itemType;
Handle handle;
Rect box, iconBox;
Str255 title;
SLocals locals;
Point mouse;
GetMouse(&mouse);
theDialog = FrontWindow();
GetDItem(theDialog, ok, &itemType, &handle, &box);
if (itemType != 4) goto bannana;
GetCTitle((ControlHandle)handle, title);
if (title[0] != 2) goto bannana;
if (title[1] != 'O') goto bannana;
if (title[2] != 'K') goto bannana;
if ((theDialog->portBits.rowBytes & 0xC000) != 0xC000) {
locals.isBWPort = true;
// BlockMove(theDialog, &locals.bwPort, sizeof(GrafPort)); /* Make a copy of the Port */
GetPort(&oldPort);
iconBox = theDialog->portRect;
OffsetRect(&iconBox, - theDialog->portBits.bounds.left, - theDialog->portBits.bounds.top);
locals.window = NewCWindow(nil, &iconBox, "\p", false, 0, (WindowPtr)-1, false, nil);
#if false
OpenCPort((CGrafPtr)&locals.colorPort); /* Init a color Port */
/* Set up the color port to match the bw port */
PortSize(theDialog->portRect.right - theDialog->portRect.left,
theDialog->portRect.bottom - theDialog->portRect.top);
MovePortTo(- theDialog->portBits.bounds.left, - theDialog->portBits.bounds.top);
CopyRgn(theDialog->visRgn, locals.colorPort.visRgn);
CopyRgn(theDialog->clipRgn, locals.colorPort.clipRgn);
BlockMove(&theDialog->pnLoc, &locals.colorPort.pnLoc, offsetof(GrafPort, pnPat) - offsetof(GrafPort, pnLoc));
BlockMove(&theDialog->pnVis, &locals.colorPort.pnVis, sizeof(GrafPort) - offsetof(GrafPort, pnVis));
#endif
SetPort(oldPort);
} else {
locals.isBWPort = false;
}
locals.filterProc = filterProc;
locals.ticks = TickCount();
locals.timedOut = false;
locals.stage = 0;
locals.oldLocals = globals->locals;
SetRect(&locals.mouseSlop, mouse.h, mouse.v,
mouse.h, mouse.v);
InsetRect(&locals.mouseSlop, -slopAmount, -slopAmount);
globals->locals = &locals;
#define CallTheOldTrap (globals->modalDialogProc)
CallTheOldTrap(MessageFilterProc, itemHit);
globals->locals = locals.oldLocals;
if (locals.timedOut) {
GetPort(&oldPort);
SetPort(theDialog);
zone = GetZone();
SetZone(SystemZone());
picture = OpenPicture(&theDialog->portRect);
SetZone(zone);
InvalRect(&theDialog->portRect);
ClipRect(&theDialog->portRect);
/* If there is a filter proc then send it an update event to force any
additional drawing. */
if (filterProc) {
EventRecord theEvent = { updateEvt, (long)theDialog, TickCount(), { 0, 0 }, 0 };
(void)filterProc(theDialog, &theEvent, itemHit);
}
if (!EmptyRgn(((WindowPeek)theDialog)->updateRgn)) {
BeginUpdate(theDialog);
DrawDialog(theDialog);
EndUpdate(theDialog);
}
iconBox.left = ((box.left + box.right) >> 1) - fingerFromLeft;
iconBox.right = iconBox.left + fingerSize;
iconBox.top = ((box.top + box.bottom) >> 1) - fingerFromTop;
iconBox.bottom = iconBox.top + fingerSize;
ClipRect(&theDialog->portRect);
PlotIconSuite(&iconBox, atNone, ttNone, globals->iconSuites[lastStage]);
ClosePicture();
HiliteControl((ControlHandle)handle, 0);
q = (Q*)NewPtrSys(sizeof(Q));
q->picture = picture;
GetDateTime(&q->dateTime);
q->windowRect = theDialog->portRect;
BlockMove((void*)CurApName, &q->appName, 32);
LocalToGlobal((Point*)&q->windowRect.top);
LocalToGlobal((Point*)&q->windowRect.bottom);
PostNotification();
if (Gestalt('Msg!', (long*)&message) == noErr) Enqueue((QElemPtr)q, &message->header);
else {
DisposePtr((Ptr)q);
KillPicture(picture);
}
SetPort(oldPort);
*itemHit = ok;
}
if (locals.isBWPort) {
DisposeWindow(locals.window);
//CloseCPort((CGrafPtr)&locals.colorPort);
}
return;
bannana:
CallTheOldTrap(filterProc, itemHit);
}
pascal Boolean MessageFilterProc(DialogPtr theDialog, EventRecord* theEvent, short* itemHit)
{
SGlobals* globals = (SGlobals*)Globals;
SLocals* locals = globals->locals;
short itemType;
Handle handle;
Rect box, iconBox;
GrafPtr currentPort;
if (((theEvent->what >= mouseDown) && (theEvent->what <= autoKey))
|| !PtInRect(theEvent->where, &locals->mouseSlop)) {
/* Brighten the control */
if (locals->stage != 0) {
RgnHandle firstMask = NewRgn();
RgnHandle secondMask = NewRgn();
GetDItem(theDialog, ok, &itemType, &handle, &box);
GetPort(¤tPort);
SetPort(theDialog);
iconBox.left = ((box.left + box.right) >> 1) - fingerFromLeft;
iconBox.right = iconBox.left + fingerSize;
iconBox.top = ((box.top + box.bottom) >> 1) - fingerFromTop;
iconBox.bottom = iconBox.top + fingerSize;
(void)IconSuiteToRgn(firstMask, &iconBox, atNone, globals->iconSuites[locals->stage - 1]);
if (locals->stage > lastStage) {
RectRgn(secondMask, &box);
UnionRgn(firstMask, secondMask, firstMask);
(*(ControlHandle)handle)->contrlHilite = 0;
}
InvalRgn(firstMask);
/* If there is a filter proc then send it an update event to force any
additional drawing. */
ClipRect(&theDialog->portRect);
EraseRgn(firstMask);
if (locals->filterProc) {
EventRecord theEvent = { updateEvt, (long)theDialog, TickCount(), { 0, 0 }, 0 };
(void)locals->filterProc(theDialog, &theEvent, itemHit);
}
if (!EmptyRgn(((WindowPeek)theDialog)->updateRgn)) {
BeginUpdate(theDialog);
DrawDialog(theDialog);
EndUpdate(theDialog);
}
DisposeRgn(firstMask);
DisposeRgn(secondMask);
SetPort(currentPort);
locals->stage = 0;
}
/* Reset the timer */
locals->ticks = TickCount();
/* Reset the mouseSlop */
SetRect(&locals->mouseSlop, theEvent->where.h, theEvent->where.v,
theEvent->where.h, theEvent->where.v);
InsetRect(&locals->mouseSlop, -slopAmount, -slopAmount);
} else if (locals->ticks + startTime + (locals->stage) * delayTime < TickCount()) {
if (locals->stage == 0) ObscureCursor();
if (locals->stage > lastStage) {
*itemHit = ok;
locals->timedOut = true;
return true;
} else {
RgnHandle firstMask = NewRgn();
RgnHandle secondMask = NewRgn();
GetDItem(theDialog, ok, &itemType, &handle, &box);
GetPort(¤tPort);
SetPort(theDialog);
iconBox.left = ((box.left + box.right) >> 1) - fingerFromLeft;
iconBox.right = iconBox.left + fingerSize;
iconBox.top = ((box.top + box.bottom) >> 1) - fingerFromTop;
iconBox.bottom = iconBox.top + fingerSize;
if (locals->stage != 0) {
(void)IconSuiteToRgn(firstMask, &iconBox, atNone, globals->iconSuites[locals->stage - 1]);
if (locals->stage == lastStage) {
RectRgn(secondMask, &box);
UnionRgn(firstMask, secondMask, firstMask);
(*(ControlHandle)handle)->contrlHilite = inButton;
}
(void)IconSuiteToRgn(secondMask, &iconBox, atNone, globals->iconSuites[locals->stage]);
DiffRgn(firstMask, secondMask, secondMask);
InvalRgn(secondMask);
/* If there is a filter proc then send it an update event to force any
additional drawing. */
ClipRect(&theDialog->portRect);
EraseRgn(secondMask);
if (locals->filterProc) {
EventRecord theEvent = { updateEvt, (long)theDialog, TickCount(), { 0, 0 }, 0 };
(void)locals->filterProc(theDialog, &theEvent, itemHit);
}
if (!EmptyRgn(((WindowPeek)theDialog)->updateRgn)) {
BeginUpdate(theDialog);
DrawDialog(theDialog);
EndUpdate(theDialog);
}
}
ClipRect(&theDialog->portRect);
if (locals->isBWPort) {
SetPort(locals->window);
CopyRgn(theDialog->visRgn, locals->window->visRgn);
// SetPort((GrafPtr)&locals->colorPort);
// BlockMove(theDialog, &locals->bwPort, sizeof(GrafPort)); /* Blast back */
// BlockMove(&locals->colorPort, theDialog, sizeof(GrafPort)); /* Blast in a color port */
}
PlotIconSuite(&iconBox, atNone, ttNone, globals->iconSuites[locals->stage]);
if (locals->isBWPort) {
SetEmptyRgn(locals->window->visRgn);
// BlockMove(&locals->bwPort, theDialog, sizeof(GrafPort)); /* Blast back */
}
DisposeRgn(firstMask);
DisposeRgn(secondMask);
SetPort(currentPort);
++locals->stage;
}
}
if (locals->filterProc) {
return locals->filterProc(theDialog, theEvent, itemHit);
} else return false;
}